﻿using System;
using System.Collections.Generic;
using System.Linq;
using WeiboPlus.Models;
using WeiboPlus.Service;

namespace WeiboPlus.Service
{
    public abstract class StatusServiceBase : SNSServiceBase<SNSStatus>, IStatusService
    {
        protected string STATUS_HOME_TIMELINE;
        protected string STATUS_MENTIONS_TIMELINE;
        protected string STATUS_SEARCH_TIMELINE;
        protected string STATUS_USER_TIMELINE;
        protected string STATUS_UPDATE;
        protected string STATUS_REPOST;
        protected string STATUS_REPLY;
        protected string COMMENT_BY_ME;
        protected string COMMENT_TO_ME;
        protected string COMMENT_BY_ID;
        protected string COMMENT_ADD;
        protected string COMMENT_DELETE;
        protected string STATUS_UPLOAD;
        protected string RESET_COUNT;
        protected string QUERY_COUNT;
        protected string COUNTS;
        protected string TRENDS_HOURLY;
        protected string TRENDS_DAILY;
        protected string TRENDS_WEEKLY;
        protected bool isActive = true;

        bool IStatusService.IsActive
        {
            get { return isActive; }
        }

        public StatusServiceBase()
        {
            Initialize();
        }

        protected abstract void Initialize();

        public StatusServiceBase(SNSAccount account)
        {
            Account = account;
        }

        public virtual void UpdateStatus(SNSRequest snsRequest, Action<SNSStatus, SNSResult> action)
        {
            var pList = GetParamtersList(snsRequest.Type);
            snsRequest.Predicate = (p) => pList.Contains(p.Name);

            PerformRequest((status,result) =>
            {
                if (action != null)
                {
                    action(status, result);
                }
               
            }, snsRequest);
        }

        public virtual void GetTimeline(SNSRequest snsRequest, Action<IList<SNSStatus>,SNSResult> action)
        {
            var pList = GetParamtersList(snsRequest.Type);
            snsRequest.Predicate = (p) => pList.Contains(p.Name);

            PerformRequest(action, snsRequest);
        }

        protected abstract override string[] GetParamtersList(SNSType type);

        public virtual void GetCounts(SNSRequest snsRequest, Action<IList<SNSCounts>, SNSResult> action)
        {
            var pList = GetParamtersList(snsRequest.Type);
            snsRequest.Predicate = (p) => pList.Contains(p.Name);

            PerformRequest(action, snsRequest);
        }

        protected abstract override IList<SNSStatus> Mapping(string res, SNSResult result);

        protected override bool TryMappingMethodString(SNSRequest snsRequest)
        {
            bool result;
            string method = string.Empty;
            switch (snsRequest.Type)
            {
                case SNSType.HomeStatus:
                    method = STATUS_HOME_TIMELINE;
                    break;
                case SNSType.MentionsStatus:
                    method = STATUS_MENTIONS_TIMELINE;
                    break;
                case SNSType.SearchStatus:
                    method = STATUS_SEARCH_TIMELINE;
                    break;
                case SNSType.AddStatus:
                    method = STATUS_UPDATE;
                    break;
                case SNSType.Upload:
                    method = STATUS_UPLOAD;
                    break;
                case SNSType.RepostStatus:
                    method = STATUS_REPOST;
                    break;
                case SNSType.CommentsByID:
                    method = COMMENT_BY_ID;
                    break;
                case SNSType.CommentsByMe:
                    method = COMMENT_BY_ME;
                    break;
                case SNSType.CommentsToMe:
                    method = COMMENT_TO_ME;
                    break;
                case SNSType.AddComment:
                    method = COMMENT_ADD;
                    break;
                case SNSType.DeleteComment:
                    method = COMMENT_DELETE;
                    break;
                case SNSType.UserStatus:
                    method = STATUS_USER_TIMELINE;
                    break;
                case SNSType.QueryCount:
                    method = QUERY_COUNT;
                    break;
                case SNSType.ResetCount:
                    method = RESET_COUNT;
                    break;
                //case SNSType.:
                //    method = RESET_COUNT;
                //    break;
                case SNSType.QueryCounts:
                    method = COUNTS;
                    break;
                case SNSType.TrendsByHour:
                    method = TRENDS_HOURLY;
                    break;
                case SNSType.TrendsByDay:
                    method = TRENDS_DAILY;
                    break;
                case SNSType.TrendsByWeek:
                    method = TRENDS_WEEKLY;
                    break;
                default:
                    break;
            }
            if (string.IsNullOrEmpty(method))
            {
                result = false;
            }
            else
            {
                snsRequest.Method = method;
                result = true;
            }
            return result;
        }

        public virtual void AddComment(SNSRequest request, Action<SNSStatus,SNSResult> action)
        {
            var pList = GetParamtersList(request.Type);
            request.Predicate = (p) => pList.Contains(p.Name);

            PerformRequest((item,result) =>
            {
                if (action != null)
                {
                    action(item, result);
                }
            }, request);
        }

        public virtual void DeleteComment(SNSRequest request, Action<SNSStatus,SNSResult> action)
        {
            var pList = GetParamtersList(request.Type);
            request.Predicate = (p) => pList.Contains(p.Name);

            PerformRequest((item,result) =>
            {
                if (action != null)
                {
                    action(item, result);
                }
            }, request);
        }

        public virtual void QueryCounts(SNSRequest request, Action<SNSCounts, SNSResult> action)
        {
            var pList = GetParamtersList(request.Type);
            request.Predicate = (p) => pList.Contains(p.Name);

            PerformRequest<SNSCounts>((item, result) =>
            {
                if (action != null)
                {
                    action(item, result);
                }
            }, request);
        }

        public virtual void ResetCounts(SNSRequest request, Action<SNSCounts,SNSResult> action)
        {
            var pList = GetParamtersList(request.Type);
            request.Predicate = (p) => pList.Contains(p.Name);

            PerformRequest<SNSCounts>((item, result) =>
            {
                if (action != null)
                {
                    action(item, result);
                }
            }, request);
        }

        public void GetTrends(SNSRequest snsRequest, Action<SNSTrends, SNSResult> action)
        {
            var pList = GetParamtersList(snsRequest.Type);
            snsRequest.Predicate = (p) => pList.Contains(p.Name);

            PerformRequest<SNSTrends>((item, result) =>
            {
                if (action != null)
                {
                    action(item, result);
                }
            }, snsRequest);
        }

        
    }
}
